#include "../StdInc.h"

namespace GSTrader
{
	namespace TradeStrategy
	{
		CInstrumentStrategy::CInstrumentStrategy(CStrategySession* pStrategySession, string strStrategyName) :
			CStrategy(pStrategySession, strStrategyName)
		{
			m_pInstrument = NULL;
		}


		CInstrumentStrategy::~CInstrumentStrategy()
		{

		}

		void CInstrumentStrategy::AddInstance(CInstrumentStrategy* pStrategy, CInstrument* pInstrument)
		{
			if (pInstrument == NULL || pStrategy == NULL || pInstrument->m_nID < 0)
			{
				assert(false);
				return;
			}

			pStrategy->m_pInstrument = pInstrument;
			pStrategy->m_pInstruments->Add(pInstrument->m_nID);
			pStrategy->m_bDispatchMsg = true;
			pStrategy->SetTradeProvider(GetStrategyTradeProvider(this, pInstrument));
			pStrategy->SetMarketDataProvider(GetStrategyMarketDataProvider(this, pInstrument));

			AddStrategy(pStrategy);
			m_pInstruments->Add(pInstrument->m_nID);

			pStrategy->m_nStatus = rsRunning;
			pStrategy->OnStrategyInit();
			pStrategy->OnStrategyStart();
		}

		void CInstrumentStrategy::StrategyInit()
		{
			if (!m_bInitialized)
			{
				for (auto x : m_pInstruments->m_vInstrumentId)
				{
					CInstrument* pInstrument = m_pFramework->m_pInstrumentManager->GetInstrumentById(x);
					if (!pInstrument)
					{
						assert(false);
						continue;
					}

					CInstrumentStrategy* pInstrumentStrategy = CreateInstance(pInstrument);
					assert(pInstrumentStrategy != NULL);

					CTradeProvider* pTradeProvider = GetStrategyTradeProvider(this, pInstrument);
					CMarketDataProvider* pMarketDataProvider = GetStrategyMarketDataProvider(this, pInstrument);
					if (pTradeProvider == NULL || pMarketDataProvider == NULL)
					{
						assert(false);
						continue;
					}

					pInstrumentStrategy->m_pInstrument = pInstrument;
					pInstrumentStrategy->m_pInstruments->Add(pInstrument->m_nID);

					pInstrumentStrategy->m_pPortfolio->CreatePosition(pInstrument->m_nID, NULL, NULL);
				
					pInstrumentStrategy->m_bDispatchMsg = true;
					pInstrumentStrategy->SetTradeProvider(pTradeProvider);
					pInstrumentStrategy->SetMarketDataProvider(pMarketDataProvider);

					AddStrategy(pInstrumentStrategy);
					pInstrumentStrategy->OnStrategyInit();
				}

				m_bInitialized = true;
			}
		}

		void CInstrumentStrategy::DoStart()
		{
			m_nStatus = rsRunning;

			if (m_bDispatchMsg)
			{
				OnStrategyStart();
			}

			for (auto p : m_mapStrategyById)
			{
				CStrategyBase* pStrategy = p.second;
				StrategySubscribe(pStrategy, pStrategy->m_pInstruments, pStrategy->m_nId);
				pStrategy->DoStart();
			}
		}

		CTradeProvider* CInstrumentStrategy::GetTradeProvider()
		{
			return CStrategy::GetTradeProvider();
		}

		CMarketDataProvider* CInstrumentStrategy::GetMarketDataProvider()
		{
			return GetStrategyMarketDataProvider(this, m_pInstrument);
		}
	}
}
